package map.tile.server.common;

import map.tile.server.dto.CoordinateXY;
import map.tile.server.dto.TileIndex;
import org.osgeo.proj4j.*;

import java.util.ArrayList;
import java.util.List;

public class CoordinateTool {

    public final static double EXTENDS_3857 = 20037508.3427892;

    /**
     * 4326坐标系转3857坐标系，自定义方法
     * @param lng
     * @param lat
     * @return
     */
    public static CoordinateXY Wgs84ToMector(double lng, double lat) {
    double radio = EXTENDS_3857 / 180;
        double x = lng * radio;
        double y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / Math.PI * 180;
        y = y * radio;
        return new CoordinateXY(x,y);
    }
    /**
     * 4326坐标系转3857坐标系，使用proj4j库
     * @param lng
     * @param lat
     * @return
     */
    public static CoordinateXY Wgs84ToMectorByProj(double lng, double lat) {
        CRSFactory crsFactory = new CRSFactory();

        // 创建源和目标的坐标参考系统
        CoordinateReferenceSystem sourceCRS = crsFactory.createFromName("EPSG:4326");
        CoordinateReferenceSystem targetCRS = crsFactory.createFromName("EPSG:3857");

        // 创建坐标转换
        CoordinateTransformFactory transformFactory = new CoordinateTransformFactory();
        CoordinateTransform transform = transformFactory.createTransform(sourceCRS, targetCRS);

        // 设置待转换的坐标
        ProjCoordinate coord = new ProjCoordinate(lng, lat);
        ProjCoordinate coordTarget = new ProjCoordinate(0, 0);
        // 转换坐标
        transform.transform(coord, coordTarget);
        return new CoordinateXY(coordTarget.x,coord.y);
    }

    /**
     * 获取指定级别坐标范围内的切片索引
     * @param xMin
     * @param yMin
     * @param xMax
     * @param yMax
     * @param level
     * @param type
     * @return
     */
    public static List<TileIndex> GetTMSCoord(double xMin,
                                              double yMin,
                                              double xMax,
                                              double  yMax,
                                              Integer level,
                                              Integer type) {
        List<TileIndex> array = new ArrayList<>();
        double tile_size = EXTENDS_3857 / Math.pow(2, level - 1);//当前等级瓦片坐标宽度（宽高相等）
        Integer x1 = (int)Math.ceil((xMin + EXTENDS_3857) / tile_size) - 1;//起始X,减1是因为从0开始
        Integer x2 = (int)Math.ceil((xMax + EXTENDS_3857) / tile_size) - 1;//终止X

        Integer y1 = 0, y2 = 0;

        switch (type) {
            case 0:
                //谷歌地图TMSy值计算
                y1 = (int)Math.ceil((EXTENDS_3857 - yMax) / tile_size) - 1;//起始y
                y2 = (int)Math.ceil((EXTENDS_3857 - yMin) / tile_size) - 1;//终止y
                break;
            case 1:
                //标准TMSy值计算
                y1 = (int)Math.ceil((yMin + EXTENDS_3857) / tile_size) - 1;//起始y
                y2 = (int)Math.ceil((yMax + EXTENDS_3857) / tile_size) - 1;//终止y
                break;
            default:
                break;
        }
        //超出范围异常计算
        if((x2-x1)*(y2-y1)>5000000){
            return array;
        }
        //防止计算产生负值
        if (x1 < 0) {
            x1 = 0;
        }
        if (x2 < 0) {
            x2 = 0;
        }
        if (y1 < 0) {
            y1 = 0;
        }
        if (y2 < 0) {
            y2 = 0;
        }
        for (Integer j = x1; j <= x2; j++) {
            for (Integer k = y1; k <= y2; k++) {
                array.add(new TileIndex(level,j,k));
                // sendDownCmd(j,k,level);
                //j就是url中的x,
                //k就是url中的y,
                //level就是地图等级对应url中的z
            }
        }

        return array;
    }
}
